package star.cloud.asme.base.security.authenticaiton;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import star.cloud.asme.base.dto.Result;
import star.cloud.asme.base.redis.RedisService;
import star.cloud.asme.base.security.jwt.JWTService;
import star.cloud.asme.system.department.DepartmentService;
import star.cloud.asme.system.user.User;
import star.cloud.asme.system.user.UserService;

@Service
@RequiredArgsConstructor
@Slf4j
public class AuthenticationServiceImpl implements AuthenticationService {
    private final UserService userService;
    private final JWTService jwtService;
    private final RedisService<String> redisService;
    private final AuthenticationManager authenticationManager;
    private final DepartmentService departmentService;

    @Override
    public Result<User> registerUser(User user) {
        log.info("registerUser is running with {}", user);
        return userService.insertOne(user);
    }

    @Override
    public Result<User> handleAuthenticateSuccess() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        User user = userService.getOneByCondition("username", username).getBody();
        setDepartment(user);
        String token = jwtService.generateToken(user);
        redisService.setOne(user.getUsername() + "-token", token);
        return Result.ok(user.toSafe()).msg("登录成功");
    }

    @Override
    public Result<User> handleAuthenticateFail() {
        return Result.error(User.builder().build()).msg("登录失败。");
    }

    @Override
    public Result<User> login(User user) {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
        authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        String token = jwtService.generateToken(user);
        User userSelected = userService.getOneByCondition("username", user.getUsername()).getBody();
        userSelected.setToken(token);
        setDepartment(userSelected);
        redisService.setOne(user.getUsername() + "-token", token);
        return Result.ok(userSelected.toSafe()).msg("登录成功");
    }

    @Override
    public Result<?> logout(String username) {
        redisService.deleteKey(username + "-token");
        return Result.ok().msg("注销成功");
    }

    private void setDepartment(User user) {
        if (user.getDepartmentId() != null) {
            user.setDepartment(departmentService.getById(user.getDepartmentId()));
        }
    }
}